﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BattleShipLibrary
{
    public class Utils
    {
        //Данный метод возвращает массив, в котором хранятся координаты точек вокруг корабля
        public int[,] GetNeighborhood(int X1, int Y1, int X2, int Y2)
        {
            int[,] array;
            List<int[]> points = new List<int[]>();
            int maxY; int minY; int maxX; int minX;
            if (Y1 == 0 || Y2 == 0)
            {
                minY = Math.Min(Y1, Y2);
            }
            else
            {
                minY = Math.Min(Y1, Y2)-1;
            }
            if (Y1 == 9 || Y2 == 9)
            {
                maxY = Math.Max(Y1, Y2);
            }
            else
            {
                maxY = Math.Max(Y1, Y2) + 1;
            }
            if (X1 == 0 || X2 == 0)
            {
                minX = Math.Min(X1, X2);
            }
            else
            {
                minX = Math.Min(X1, X2) - 1;
            }
            if (X1 == 9 || X2 == 9)
            {
                maxX = Math.Max(X1, X2);
            }
            else
            {
                maxX = Math.Max(X1, X2)+1;
            }
                int[,] shipPoints;
                if (X1 == X2)
                {
                    shipPoints = new int[Math.Abs(Math.Max(Y1, Y2) - Math.Min(Y1, Y2)+1), 2];
                    for(int i=0; i <Math.Abs(Y1 - Y2+1); i++){
                        shipPoints[i, 0] = X1;
                        shipPoints[i, 1] = Math.Min(Y1, Y2) + i;
                    }
                }
                else
                {
                    shipPoints = new int[Math.Abs(Math.Max(X1, X2) - Math.Max(X1, X2)+1), 2];
                    for (int i = 0; i < Math.Abs(Math.Max(X1, X2) - Math.Max(X1, X2)+1); i++)
                    {
                        shipPoints[i, 0] = Y1;
                        shipPoints[i, 1] = Math.Min(X1, X2) + i;
                    }
                }
                maxX = Math.Max(X1, X2) + 1;
                
                //Обход правого столбца
                for (int i = minY; i <= maxY; i++)
                {
                    for (int j = 0; j < shipPoints.Length / shipPoints.Rank; j++)
                    {
                        if (i != shipPoints[j, 0] || maxX != shipPoints[j, 1])
                        {

                            int[] arr2 = new int[2] { maxX, i }; ;
                            points.Add(arr2);
                        }
                    }
                }
                //Обход левого столбца
                for (int i = minY; i <= maxY; i++)
                {
                    for (int j = 0; j < shipPoints.Length / shipPoints.Rank; j++)
                    {
                        if (i != shipPoints[j, 0] || minX != shipPoints[j, 1])
                        {
                            int[] arr2 = new int[2] { minX, i };
                            points.Add(arr2);
                        }
                    }
                }

                //Обход нижней строки
                for (int i = minX; i <= maxX; i++)
                {
                    for (int j = 0; j < shipPoints.Length / shipPoints.Rank; j++)
                    {
                        if (i != shipPoints[j, 1] || maxY != shipPoints[j, 0])
                        {
                            int[] arr2 = new int[2] { i, maxY };
                            points.Add(arr2);
                        }
                    }
                }
                //Обход верхней строки
                for (int i = minX; i <= maxX; i++)
                {
                    for (int j = 0; j < shipPoints.Length / shipPoints.Rank; j++)
                    {
                        if (i != shipPoints[j, 1] || minY != shipPoints[j, 0])
                        {
                            int[] arr2 = new int[2] { i, minY };
                            points.Add(arr2);
                        }
                    }
                }



                //Удаляем повторяющиеся ячейки
                for (int i = 0; i < points.Count; i++)
                {
                    for (int j = 0; j < points.Count; j++)
                    {
                        if (points[i][0] == points[j][0] && points[i][1] == points[j][1] && j != i)
                        {
                            points.RemoveAt(j);
                            j = 0;
                        }
                    }


                }

            array = new int[points.Count, 2];
            for (int i = 0; i < points.Count; i++)
            {
                array[i, 0] = points[i][0];
                array[i, 1] = points[i][1];
            }
            //Console.WriteLine(array.Length);
            return array;
        }

        public class ShipAddingException : Exception
        {
            public ShipAddingException() { }
            public ShipAddingException(string message) : base(message) { }
            public ShipAddingException(string message, Exception inner) : base(message, inner) { }
            protected ShipAddingException(
              System.Runtime.Serialization.SerializationInfo info,
              System.Runtime.Serialization.StreamingContext context)
                : base(info, context) { }
        }
    }
}
